package com.lippeng.taohua.db.domain;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import com.lippeng.taohua.db.connection.ConnectionPool;

/**
 * This class is the bridge of SuperDomain and ImplementDomain.
 * 
 * I used the DynamicProxy of JDK to implement AOP.
 * 
 * Before one SuperDomain Object is created success,
 * 
 * one ProxyDomain Object and one ImplementDomain is already created.
 * 
 * @author lippeng
 * 
 */
public class ProxyDomain implements InvocationHandler {

	/**
	 * This field is the real object to do DML with DataBase
	 */
	private ImplementDomain implementDomain;

	/**
	 * Get and back connection
	 */
	private ConnectionPool connectionPool;

	/**
	 * Constructor
	 * @param domain 
	 */
	private ProxyDomain(SuperDomain domain) {
		implementDomain = new ImplementDomain(domain);
		connectionPool = ConnectionPool.getConnectionPool();
	}

	/**
	 * Initialize this Object and Return the ProxyDomain
	 * @param domain 
	 * 
	 * @return
	 */
	public static IDomain getProxyDomain(SuperDomain domain) {
		return (IDomain) Proxy.newProxyInstance(IDomain.class.getClassLoader(),
				IDomain.class.getInterfaces(), new ProxyDomain(domain));
	}

	/**
	 * Override InvocationHandler and implement the DynamicProxy
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result;

		// 方法调用之前
		doBefore();

		// 调用原始对象的方法
		result = method.invoke(this.implementDomain, args);

		// 方法调用之后
		doAfter();

		return result;
	}

	/**
	 * Do this before do the real thing
	 */
	private void doBefore() {
		implementDomain.setConnection(connectionPool.getConnection());
	}

	/**
	 * Do this after the core work
	 */
	private void doAfter() {
		connectionPool.backConnection(implementDomain.getConnection());
	}

}
